﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace new_problem
{
    /**
     * Класс содержит функции возвращающие значение одномерного шумового сигнала с матожиданием 0 и амплитудой до amp
     */ 
    class Noise
    {
        Random rnd1;
        Random rnd2;

        public Noise() {
            rnd1 = new Random();
            rnd2 = new Random();
        }

        //Гауссов шум
        public Double getGaussianNoise(Double amp, Double prob)
        {
            if(prob>=rnd1.NextDouble())
                return amp*Math.Cos(2 * Math.PI * rnd1.NextDouble()) * Math.Sqrt(-2 * Math.Log(rnd2.NextDouble()));//Преобразование Бокса-Мюллера
            return 0;
        }

        //Белый шум
        public Double getWhiteNoise(Double amp, Double prob)
        {
            if (prob >= rnd1.NextDouble())
                return amp * (rnd1.NextDouble() - 0.5) * 2.0;
            return 0;
        }

        //Шум "соль-перец" (импульсный шум)
        public Double getImpulseNoise(Double amp, Double prob)
        {
            if (prob >= rnd1.NextDouble())
                if (0.5 >= rnd1.NextDouble())
                    return amp;
                else
                    return -amp;
            return 0;
        }

        public Double[,] addNoise(Double[,] z, Double amp, Double prob, int type)
        {
            Double[,] result = z;
            switch (type)
            {
                case 0:
                    for (int i = 0; i < DataGen.N + 1; i++)
                    {
                        for (int j = 0; j < DataGen.N + 1; j++)
                        {
                            result[i, j] += this.getGaussianNoise(amp, prob);
                        }
                    }
                    return z;
                    break;
                case 1:
                    for (int i = 0; i < DataGen.N + 1; i++)
                    {
                        for (int j = 0; j < DataGen.N + 1; j++)
                        {
                            result[i, j] += this.getWhiteNoise(amp, prob);
                        }
                    }
                    return z;
                    break;
                case 2:
                    for (int i = 0; i < DataGen.N + 1; i++)
                    {
                        for (int j = 0; j < DataGen.N + 1; j++)
                        {
                            result[i, j] += this.getImpulseNoise(amp, prob);
                        }
                    }
                    return result;
                    break;
                default:
                    return z;

            }
        }
    }
}
